Add ABI frame lowering layers#1947
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| \n### CI Failure Hints\n\nFailed jobs: `checks`\n\nCopy-paste local triage:\n```bash\nmake check\nlake build\nFOUNDRY_PROFILE=difftest forge test -vv\n``` |
| | .calldata => YulExpr.call "calldataload" [sourceByteOffset field idx] | ||
| | .memory => YulExpr.call "mload" [sourceByteOffset field idx] | ||
| | .code => YulExpr.call "mload" [sourceByteOffset field idx] | ||
| | .storage => YulExpr.call "sload" [sourceStorageSlot field idx] |
There was a problem hiding this comment.
Code frame source uses mload
High Severity
For FrameSource.code, materializeSourceWord uses mload on the field’s base identifier, same as memory. That reads contract RAM at a pointer, not runtime bytecode at an address, so spilled frames and inline args from .code fields can be wrong when the base is a contract pointer.
Reviewed by Cursor Bugbot for commit 54a6024. Configure here.
| ]), | ||
| YulStmt.expr (YulExpr.call "return" [ | ||
| YulExpr.ident "__return_code_ptr", | ||
| YulExpr.ident "__return_code_size" |
There was a problem hiding this comment.
returnCodeData copies whole bytecode
Medium Severity
returnCodeData uses extcodesize and extcodecopy from offset zero for the full code length. SSTORE2-style layouts and CodeData reads often skip a leading bytecode prefix via codeOffset, so returndata can include non-ABI bytes and break decoding of declared struct/tuple returns.
Reviewed by Cursor Bugbot for commit 54a6024. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 25bb096. Configure here.
| (List.range (fieldPayloadWords field)).map fun idx => | ||
| YulStmt.expr (YulExpr.call "mstore" | ||
| [ YulExpr.call "add" [YulExpr.ident (ptrName base), YulExpr.lit ((offsetWords + idx) * 32)] | ||
| , materializeSourceWord field idx ]) |
There was a problem hiding this comment.
Dynamic calldata tail copied wrongly
High Severity
spillField loads dynamic fields as consecutive words from each field’s calldata base. ABI-encoded dynamic bytes/arrays store an offset in the head and place tail data elsewhere, so sequential calldataload after the head does not reproduce the tail or valid in-memory ABI layout.
Reviewed by Cursor Bugbot for commit 25bb096. Configure here.


Summary
Compiler.ABI.Frametyped ABI frame layouts for nested structs, dynamic bytes/arrays, and calldata/memory/code/storage sourcesCompiler.Lowering.StackSafeAbiframe-spilled lowering for events, external calls, and dynamic returns so large payloads are materialized in memory and passed as pointersCompiler.Modules.CodeDatatyped CREATE2/SSTORE2 code-as-data read/write facade with explicit trust surface and roundtrip shape testsCompiler.Proofs.GeneratedTransitionminimal reads/writes/guards/events extraction for later Midnight RCF/totalUnits wiringVerification
lake build Compiler.ABI.FrameTest Compiler.Lowering.StackSafeAbiTest Compiler.Modules.CodeDataTest Compiler.Proofs.GeneratedTransitionTestlake build Compiler.Moduleslake build CompilerNote
Medium Risk
New runtime return path (
returnCodeData) and pointer-based ABI lowering touch codegen and EVM introspection boundaries; mostly additive with tests but incorrect frame sizing or extcodecopy semantics would break calls/returns.Overview
Introduces typed ABI frame layouts (
Compiler.ABI.Frame) that choose inline words vs memory(ptr, size)for nested structs and dynamic tails, plusStackSafeAbihelpers to spill payloads before events, external calls, and dynamic returns.Adds
Stmt.returnCodeDataend-to-end: Yul viaextcodesize/extcodecopy, validation/trust-surface tagging, macroreturnCodeData, and aCodeDataReturnSmokecontract example.Compiler.Modules.CodeDatawraps CREATE2/SSTORE2 read/write on those frames with an explicit trust surface.Also adds
GeneratedTransition(reads/writes/guards/events from stmt lists) for later proof wiring, and maps struct return types to tupleParamTypein the macro translator.Reviewed by Cursor Bugbot for commit 25bb096. Bugbot is set up for automated code reviews on this repo. Configure here.